package demoMod.moduploader.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import demoMod.gdxform.core.AbstractAction;
import demoMod.gdxform.core.FormManager;
import demoMod.gdxform.enums.GFrameWindowMode;
import demoMod.gdxform.enums.GFrameWindowStyle;
import demoMod.gdxform.helpers.FontHelper;
import demoMod.gdxform.interfaces.Element;
import demoMod.gdxform.ui.*;
import demoMod.moduploader.core.MainWindow;
import demoMod.moduploader.fonts.FontKeys;
import demoMod.moduploader.interfaces.Refreshable;
import demoMod.moduploader.localization.LocalizedStrings;
import demoMod.moduploader.model.ModInfo;

import java.util.ArrayList;
import java.util.List;

public class ModInfoWindow extends GFrame implements Refreshable {
    private final ModDisplayItem modDisplayItem;
    private final GTextField modTitle;
    private final GTextField modDescription;
    private final GButton modVisibility;
    private final GLabel currentVisibility;
    private final GTextField changeNote;
    private final GButton addLabel;
    private final GButton removeLabel;
    private final GList<GLabel> labels;
    private final GScrollPane scrollPane;
    private final GButton uploadButton;
    private final ModDisplayItem modCover;

    public ModInfoWindow(BitmapFont bannerFont, ModDisplayItem modDisplayItem) {
        super(Gdx.graphics.getWidth() * 0.05F, Gdx.graphics.getHeight() * 0.05F - 10, Gdx.graphics.getWidth() * 0.9F, Gdx.graphics.getHeight() * 0.9F, bannerFont, GFrameWindowStyle.CLOSE_BUTTON_ONLY, false);
        setWindowMode(GFrameWindowMode.MODAL);
        List<String> strings = LocalizedStrings.getStrings("ModInfoWindow");
        setTitle(String.format(strings.get(0), modDisplayItem.getModInfoCache().title));
        this.modDisplayItem = modDisplayItem;
        modCover = new ModDisplayItem(bannerFont, modDisplayItem.getModUploadItem()) {
            @Override
            public float getX(boolean isAbsolute) {
                return getParent() != null ? getParent().getX(isAbsolute) + getParent().getWidth() * 0.55F : 0;
            }

            @Override
            public float getY(boolean isAbsolute) {
                return getParent() != null ? getParent().getY(isAbsolute) + getParent().getHeight() * 0.43F : 0;
            }

            @Override
            public float getWidth() {
                return getParent() != null ? getParent().getWidth() * 0.4F : Gdx.graphics.getWidth();
            }

            @Override
            public float getHeight() {
                return getParent() != null ? getParent().getWidth() * 0.4F : Gdx.graphics.getHeight();
            }

            @Override
            public boolean clickDown(int screenX, int screenY, int button) {
                return false;
            }
        };
        modCover.setShowTitle(false);
        addElement(modCover);

        GLabel lblTitle = new GLabel(getWidth() * 0.05F, getHeight() * 0.9F, 300.0F, bannerFont.getLineHeight(), bannerFont);
        lblTitle.setText(strings.get(1));
        addElement(lblTitle);
        modTitle = new GTextField(getWidth() * 0.05F + 100.0F, getHeight() * 0.9F - bannerFont.getLineHeight() / 2.0F, getWidth() * 0.5F - 100.0F, bannerFont.getLineHeight() * 1.25F, bannerFont) {
            @Override
            public boolean keyDown(int keyCode) {
                if (keyCode == Input.Keys.ENTER && FormManager.getInstance().getEventHooks().getCurrentFocusedElement() == this) {
                    FormManager.getInstance().getEventHooks().setCurrentFocusedElement(getParent());
                    return true;
                }
                return super.keyDown(keyCode);
            }

            @Override
            public void deactivate() {
                super.deactivate();
                modDisplayItem.getModInfoCache().title = getText();
                modDisplayItem.getModUploadItem().saveConfigFile(modDisplayItem.getModInfoCache());
                modDisplayItem.refresh();
            }
        };
        modTitle.setText(modDisplayItem.getModInfoCache().title);
        modTitle.setTextColor(Color.WHITE.cpy());
        modTitle.setBackground(Color.DARK_GRAY.cpy());

        addElement(modTitle);
        GLabel lblDescription = new GLabel(getWidth() * 0.05F, getHeight() * 0.85F, 300.0F, bannerFont.getLineHeight(), bannerFont);
        lblDescription.setText(strings.get(2));
        addElement(lblDescription);
        modDescription = new GTextField(getWidth() * 0.05F + 100.0F, getHeight() * 0.85F - bannerFont.getLineHeight() / 2.0F, getWidth() * 0.5F - 100.0F, bannerFont.getLineHeight() * 1.25F, bannerFont) {
            @Override
            public boolean keyDown(int keyCode) {
                if (keyCode == Input.Keys.ENTER && FormManager.getInstance().getEventHooks().getCurrentFocusedElement() == this) {
                    FormManager.getInstance().getEventHooks().setCurrentFocusedElement(getParent());
                    return true;
                }
                return super.keyDown(keyCode);
            }

            @Override
            public void deactivate() {
                super.deactivate();
                modDisplayItem.getModInfoCache().description = getText();
                modDisplayItem.getModUploadItem().saveConfigFile(modDisplayItem.getModInfoCache());
                modDisplayItem.refresh();
            }
        };
        modDescription.setText(modDisplayItem.getModInfoCache().description);
        modDescription.setTextColor(Color.WHITE.cpy());
        modDescription.setBackground(Color.DARK_GRAY.cpy());
        addElement(modDescription);
        List<String> visibilityStrings = LocalizedStrings.getStrings("ModVisibility");
        modVisibility = new GButton(getWidth() * 0.05F, getHeight() * 0.8F - bannerFont.getLineHeight() / 2.0F, 150.0F, bannerFont.getLineHeight(), bannerFont) {
            @Override
            public void onClick() {
                List<String> options = new ArrayList<>();
                options.add(visibilityStrings.get(1));
                options.add(visibilityStrings.get(2));
                options.add(visibilityStrings.get(3));
                new OptionWindow(strings.get(3), options, bannerFont, getVisibilityIndex(modDisplayItem.getModInfoCache().visibility) - 1).setConfirmCallback(index -> {
                    switch (index) {
                        case 0:
                            modDisplayItem.getModInfoCache().visibility = "public";
                            break;
                        case 1:
                            modDisplayItem.getModInfoCache().visibility = "friends";
                            break;
                        case 2:
                        default:
                            modDisplayItem.getModInfoCache().visibility = "private";
                            break;
                    }
                    modDisplayItem.getModUploadItem().saveConfigFile(modDisplayItem.getModInfoCache());
                    modDisplayItem.refresh();
                    currentVisibility.setText(String.format(visibilityStrings.get(0), visibilityStrings.get(getVisibilityIndex(modDisplayItem.getModInfoCache().visibility))));
                });
            }
        };
        modVisibility.setText(strings.get(3) + "...");
        modVisibility.setBackground(MainWindow.steamBgColor.cpy());
        modVisibility.setBorderWidth(2);
        modVisibility.setBorder(Color.SKY.cpy());
        addElement(modVisibility);
        currentVisibility = new GLabel(getWidth() * 0.05F + 160.0F, getHeight() * 0.8F, 150.0F, bannerFont.getLineHeight(), bannerFont);
        currentVisibility.setText(String.format(visibilityStrings.get(0), visibilityStrings.get(getVisibilityIndex(modDisplayItem.getModInfoCache().visibility))));
        addElement(currentVisibility);
        GLabel lblChangeNote = new GLabel(getWidth() * 0.05F, getHeight() * 0.75F, 150.0F, bannerFont.getLineHeight(), bannerFont);
        lblChangeNote.setText(strings.get(4));
        addElement(lblChangeNote);
        changeNote = new GTextField(getWidth() * 0.05F + 100.0F, getHeight() * 0.75F - bannerFont.getLineHeight() / 2.0F, getWidth() * 0.5F - 100.0F, bannerFont.getLineHeight() * 1.25F, bannerFont) {
            @Override
            public boolean keyDown(int keyCode) {
                if (keyCode == Input.Keys.ENTER && FormManager.getInstance().getEventHooks().getCurrentFocusedElement() == this) {
                    FormManager.getInstance().getEventHooks().setCurrentFocusedElement(getParent());
                    return true;
                }
                return super.keyDown(keyCode);
            }

            @Override
            public void deactivate() {
                super.deactivate();
                modDisplayItem.getModInfoCache().changeNote = getText();
                modDisplayItem.getModUploadItem().saveConfigFile(modDisplayItem.getModInfoCache());
                modDisplayItem.refresh();
            }
        };
        changeNote.setText(modDisplayItem.getModInfoCache().changeNote);
        changeNote.setTextColor(Color.WHITE.cpy());
        changeNote.setBackground(Color.DARK_GRAY.cpy());
        addElement(changeNote);
        addLabel = new GButton(getWidth() * 0.05F, getHeight() * 0.7F, 150.0F, bannerFont.getLineHeight(), bannerFont) {
            @Override
            public void onClick() {
                new TextInputWindow(strings.get(5), "", bannerFont).setConfirmCallback(tag -> {
                    GLabel label = new GButton(0, 0, labels.getCellWidth(), labels.getCellHeight(), FontHelper.getFont(FontKeys.SIM_HEI_16_BOLD));
                    label.setText(tag);
                    label.setColor(Color.WHITE.cpy());
                    labels.addItem(label);
                    List<String> tags = new ArrayList<>();
                    for (GList.ListCellRenderer<GLabel> cellRenderer : labels.getElements()) {
                        tags.add(cellRenderer.getElements().get(0).getText());
                    }
                    modDisplayItem.getModInfoCache().tags = tags.toArray(new String[0]);
                    modDisplayItem.getModUploadItem().saveConfigFile(modDisplayItem.getModInfoCache());
                    modDisplayItem.refresh();
                });
            }
        };
        addLabel.setText(strings.get(5));
        addLabel.setBackground(MainWindow.steamBgColor.cpy());
        addLabel.setBorderWidth(2);
        addLabel.setBorder(Color.SKY.cpy());
        addElement(addLabel);
        removeLabel = new GButton(getWidth() * 0.05F + 155.0F, getHeight() * 0.7F, 150.0F, bannerFont.getLineHeight(), bannerFont) {
            @Override
            public void onClick() {
                if (labels.getSelectedItems().isEmpty()) {
                    return;
                }
                labels.removeItem(labels.getSelectedItems().get(0));
                actionManager.addToSequenceBot(new AbstractAction.Builder().setActionBody(dur -> {
                    List<String> tags = new ArrayList<>();
                    for (GList.ListCellRenderer<GLabel> cellRenderer : labels.getElements()) {
                        tags.add(cellRenderer.getElements().get(0).getText());
                    }
                    modDisplayItem.getModInfoCache().tags = tags.toArray(new String[0]);
                    modDisplayItem.getModUploadItem().saveConfigFile(modDisplayItem.getModInfoCache());
                    modDisplayItem.refresh();
                    return true;
                }).build());
            }
        };
        removeLabel.setText(strings.get(6));
        removeLabel.setBackground(MainWindow.steamBgColor.cpy());
        removeLabel.setBorderWidth(2);
        removeLabel.setBorder(Color.SKY.cpy());
        addElement(removeLabel);
        scrollPane = new GScrollPane(getWidth() * 0.05F, getHeight() * 0.47F, getWidth() * 0.5F, getHeight() * 0.2F, getWidth() * 0.5F, getHeight());
        GVScrollBar scrollBar = new GVScrollBar(0, 0, 10, scrollPane.getHeight());
        scrollBar.setBarLength(scrollPane.getHeight() * 0.2F);
        scrollPane.setVScrollBar(scrollBar);
        scrollPane.setBackground(Color.WHITE.cpy());
        scrollPane.setBackground(MainWindow.steamBgColor.cpy());
        labels = new GList<>();
        labels.setColumns(1);
        labels.setCellWidth(scrollPane.getWidth());

        for (String tag : modDisplayItem.getModInfoCache().tags) {
            GLabel label = new GButton(0, 0, labels.getCellWidth(), labels.getCellHeight(), FontHelper.getFont(FontKeys.SIM_HEI_16_BOLD));
            label.setText(tag);
            label.setColor(Color.WHITE.cpy());
            labels.addItem(label);
        }

        scrollPane.addElement(labels);
        addElement(scrollPane);
        uploadButton = new GButton(getWidth() * 0.05F, 10.0F, getWidth() * 0.9F, 60.0F, bannerFont) {
            @Override
            public void onClick() {
                new ModUploadWindow(bannerFont, modDisplayItem, modDisplayItem.getModInfoCache().steamPublishedID != null);
            }
        };
        uploadButton.setText(strings.get(modDisplayItem.getModInfoCache().steamPublishedID == null ? 7 : 8));
        uploadButton.setBackground(Color.FOREST.cpy());
        addElement(uploadButton);
    }

    private int getVisibilityIndex(String visibility) {
        if (visibility.startsWith("private")) {
            return 3;
        }
        if (visibility.startsWith("public")) {
            return 1;
        }
        if (visibility.startsWith("friend")) {
            return 2;
        }
        return 3;
    }

    @Override
    public void refresh() {
        if (modDisplayItem.getModInfoCache() == null) {
            performCloseAction();
            return;
        }
        List<String> strings = LocalizedStrings.getStrings("ModInfoWindow");
        modDisplayItem.refresh();
        ModInfo modInfo = modDisplayItem.getModInfoCache();
        setTitle(String.format(strings.get(0), modInfo.title));
        modCover.refresh();
        modTitle.setText(modInfo.title);
        modDescription.setText(modInfo.description);
        List<String> visibilityStrings = LocalizedStrings.getStrings("ModVisibility");
        currentVisibility.setText(String.format(visibilityStrings.get(0), visibilityStrings.get(getVisibilityIndex(modInfo.visibility))));
        changeNote.setText(modInfo.changeNote);
        for (Element element : labels.getElements()) {
            element.dispose();
        }
        labels.clear();
        for (String tag : modDisplayItem.getModInfoCache().tags) {
            GLabel label = new GButton(0, 0, labels.getCellWidth(), labels.getCellHeight(), FontHelper.getFont(FontKeys.SIM_HEI_16_BOLD));
            label.setText(tag);
            label.setColor(Color.WHITE.cpy());
            labels.addItem(label);
        }
    }
}
